#include "videodownloader.h"
#include <QNetworkRequest>
#include <QJsonDocument>
#include <QDebug>
#include <QDir>
#include <QStandardPaths>
#include <QNetworkReply>

VideoDownloader::VideoDownloader(QObject *parent)
    : QObject(parent),
      networkManager(new QNetworkAccessManager(this)),
      timer(new QTimer(this)),
      serverUrl("http://47.109.75.129:3000/videos"),
      //downloadPath(QDir::currentPath()),
      downloadPath(QDir::currentPath() + "/videos"), // 使用当前项目目录下的 videos 子目录
      currentDownload(nullptr)
{
    // 设置定时器（每5分钟检查一次）
    timer->setInterval(60 * 1000); // 1分钟
    connect(timer, &QTimer::timeout, this, &VideoDownloader::onTimerTimeout);
    connect(networkManager, &QNetworkAccessManager::finished, this, &VideoDownloader::onGetVideosFinished);
}

VideoDownloader::~VideoDownloader()
{
    if (currentDownload) {
        currentDownload->abort();
        currentDownload->deleteLater();
    }
}

void VideoDownloader::start()
{
    qDebug() << "start timer...";
    timer->start();
}

void VideoDownloader::onTimerTimeout()
{
    qDebug() << "start checking netVideos...";
    fetchVideos();
}

void VideoDownloader::fetchVideos()
{
    QNetworkRequest request(serverUrl);
    networkManager->get(request);
}

void VideoDownloader::onGetVideosFinished(QNetworkReply *reply)
{
    if (reply->error() != QNetworkReply::NoError) {
        qDebug() << "get video fail" << reply->errorString();
        return;
    }

    QByteArray data = reply->readAll();

    qDebug() << "server reply" << data; // 打印原始响应

    QJsonDocument doc = QJsonDocument::fromJson(data);
    if (doc.isNull() || !doc.isArray()) {
        qDebug() << "analyze JSON fail";
        return;
    }

    QJsonArray videos = doc.array();
    if (videos.isEmpty()) {
        qDebug() << "no video";
        return;
    }

    int latestId = -1;
    QString latestUrl;
    QString latestFilename;

    for (const QJsonValue &val : videos) {
        if (!val.isObject()) continue;
        QJsonObject obj = val.toObject();

        int id = obj.value("id").toInt();
        QString url = obj.value("url").toString();
        QString filename = obj.value("filename").toString();

        if (id > latestId) {
            latestId = id;
            latestUrl = url;
            latestFilename = filename;
        }
    }

    if (!latestUrl.isEmpty()) {
        qDebug() << "latest video" << latestFilename << "(ID:" << latestId << ")";
        downloadVideo(latestUrl, latestFilename);
    }
}

void VideoDownloader::downloadVideo(const QString &url, const QString &filename)
{
    if (currentDownload) {
        currentDownload->abort();
        currentDownload->deleteLater();
    }

    QUrl videoUrl(url);
    QNetworkRequest request(videoUrl);
    currentDownload = networkManager->get(request);

    QString localPath = downloadPath + "/" + filename;
    QFile *file = new QFile(localPath, this);

    if (!file->open(QIODevice::WriteOnly)) {
        qDebug() << "cannot open file" << localPath;
        file->deleteLater();
        return;
    }

    currentDownload->setProperty("file", QVariant::fromValue<QObject*>(file));

    connect(currentDownload, &QNetworkReply::readyRead, this, [this, file]() {
        if (file && currentDownload) {
            file->write(currentDownload->readAll());
        }
    });

    connect(currentDownload, &QNetworkReply::finished, this, &VideoDownloader::onDownloadFinished);
}

void VideoDownloader::onDownloadProgress(qint64 bytesReceived, qint64 bytesTotal)
{
    qDebug() << "下载进度：" << bytesReceived << "/" << bytesTotal;
}

void VideoDownloader::onDownloadFinished()
{
    QNetworkReply *reply = qobject_cast<QNetworkReply*>(sender());
    if (!reply) return;

    if (reply->error() != QNetworkReply::NoError) {
        qDebug() << "download fail" << reply->errorString();
        reply->deleteLater();
        return;
    }

    QFile *file = reply->property("file").value<QFile*>();
    if (file) {
        while (!reply->atEnd()) {
            file->write(reply->readAll());
        }
        file->flush();
        file->close();
        qDebug() << "download finish" << file->fileName();
        file->deleteLater();
    }

    reply->deleteLater();
}
